<template>
  <div class="cascader-item">
    <div
      class="left"
      :style="{ minWidth: config.width + 'px' }"
      :class="{ bl: level == 0, br: !lists || level + 1 == config.level }"
    >
      <div
        class="title"
        :class="{ btlr: level == 0, btrr: !lists || level + 1 == config.level }"
      >
        <span v-if="config.levelName && config.levelName.length">{{
          config.levelName[this.level]
        }}</span>
        <span v-else>{{ (level + 1) | transform }}级选项栏</span>
      </div>
      <div class="content" ref="ul-list">
        <div v-if="!data.length && !isAdd" class="empty">
          <a-empty />
        </div>
        <ul>
          <li
            v-for="(item, index) in data"
            :key="index"
            :id="item.id"
            @click.stop="select(item, level)"
            :style="{
              background: isActive(item.value) ? config.activeColor : '',
            }"
          >
            <div class="add-option" v-if="isEdit && isActive(item.value)">
              <div class="input">
                <a-input
                  v-model="addOption.value"
                  disabled
                  placeholder="请输入选项值（如：1）"
                />
                <a-space style="visibility: hidden">
                  <a-icon type="check" @click="confirm(false)" />
                  <a-icon type="close" @click="cancel" />
                </a-space>
              </div>
              <div class="input">
                <a-input
                  v-model="addOption.label"
                  placeholder="请输入选项名（如：选项1）"
                />
                <a-space>
                  <a-icon type="check" @click="confirm(false)" />
                  <a-icon type="close" @click="cancel" />
                </a-space>
              </div>
            </div>
            <div v-else class="li-style">
              <span>
                {{ item.label }}
              </span>
              <a-space :class="{ btn: !config.alwaysShow }">
                <a-icon
                  v-if="index != 0 && config.canMove"
                  type="vertical-align-top"
                  @click.stop="move(item, 'ontop')"
                  title="置顶"
                />
                <a-icon
                  v-if="index != 0 && config.canMove"
                  type="arrow-up"
                  @click.stop="move(item, 'up')"
                  title="上移"
                />
                <a-icon
                  v-if="index != down && config.canMove"
                  type="arrow-down"
                  @click.stop="move(item, 'down')"
                  title="下移"
                />
                <a-icon
                  v-if="config.canEdit"
                  type="edit"
                  @click.stop="edit(item)"
                  title="编辑"
                />
                <a-icon
                  v-if="config.canDelete"
                  type="delete"
                  @click="delData(item)"
                  title="删除"
                />
              </a-space>
            </div>
          </li>
        </ul>
        <div class="add-option" v-if="isAdd">
          <div class="input">
            <a-input
              v-model="addOption.value"
              placeholder="请输入选项值（如：1）"
            />
            <a-space style="visibility: hidden">
              <a-icon type="check" @click="confirm(true)" />
              <a-icon type="close" @click="cancel" />
            </a-space>
          </div>
          <div class="input">
            <a-input
              v-model="addOption.label"
              placeholder="请输入选项名（如：选项1）"
            />
            <a-space>
              <a-icon type="check" @click="confirm(true)" />
              <a-icon type="close" @click="cancel" />
            </a-space>
          </div>
        </div>
      </div>
      <div
        class="add-plus"
        :class="{ bbrr: !lists || level + 1 == config.level, bblr: level == 0 }"
      >
        <span @click="addOptions">
          <a-icon type="plus" class="mgr-10" />新增选项
        </span>
      </div>
    </div>
    <div class="right" v-if="lists && level + 1 < config.level">
      <a-divider type="vertical" class="divider" />
      <CascaderItem
        :data="lists"
        :selectData="selectData"
        :level="level + 1"
        @change="change"
        @add="add"
        @deal="deal"
        :config="config"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: "CascaderItem",
  props: {
    // 数组
    data: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 选中数组
    selectData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    // 配置项
    config: {
      type: Object,
      default: () => {
        return {};
      },
    },
    // 层级数
    level: {
      type: [Number, String],
      default: 0,
    },
  },
  data() {
    return {
      // 新增/编辑数据对象
      addOption: {},
      // 是否是新增按钮
      isAdd: false,
      // 是否是编辑按钮
      isEdit: false,
    };
  },
  computed: {
    // 组件的data值来源
    lists() {
      return this.selectData?.[this.level]?.children;
    },
    selectLists() {
      return this.selectData?.[this.level - 1]?.children;
    },
    // 是否向下
    down() {
      if (this.level == 0) {
        return this.data?.length - 1;
      } else {
        return this.selectLists?.length - 1;
      }
    },
    // 是否选中
    isActive() {
      return (value) => {
        return this.selectData?.[this.level]?.value === value || false;
      };
    },
  },
  mounted() {},

  methods: {
    // 新增选项
    addOptions() {
      this.isAdd = true;
      this.isEdit = false;
      this.scroll();
    },
    // 编辑选项
    edit(item) {
      this.isEdit = true;
      this.isAdd = false;
      this.select(item, item.level);
      this.addOption = JSON.parse(JSON.stringify(item));
    },
    // 移动选项行
    move(item, type) {
      this.select(item, item.level);
      this.deal(item, type);
    },
    // 数据改变
    change(newValue) {
      // 向顶层传递数据改变信息
      this.$emit("change", newValue);
    },
    // 新增/编辑数据
    add(newValue, isAdd) {
      this.$emit("add", newValue, isAdd);
    },
    // 滚动到底部
    scroll() {
      this.$nextTick(() => {
        this.$refs["ul-list"].scrollTop = this.$refs["ul-list"].scrollHeight;
      });
    },
    // 处理数据
    deal(newValue, type = "") {
      this.$emit("deal", newValue, type);
    },
    // 删除方法
    delData(item) {
      let that = this;
      this.$confirm({
        title: "删除提示",
        content: "是否确定删除该选项",
        okText: "确认",
        cancelText: "取消",
        onOk() {
          that.deal(item);
        },
        onCancel() {},
      });
    },
    // 确认新增选项
    confirm(item) {
      if (item) {
        this.addData(item);
      } else {
        this.editData(item);
      }
    },
    // 取消
    cancel() {
      this.isAdd = false;
      this.isEdit = false;
      this.addOption = {};
    },
    // 新增/编辑数据
    addData(item) {
      // 判断是否已存在
      const list =
        this.level == 0
          ? this.data?.map((v) => v.value)
          : this.selectLists?.map((v) => v.value);
      if (list && list?.includes(this.addOption?.value)) {
        this.$message.error("选项值重复，新增失败!");
        return false;
      } else if (!this.addOption?.value) {
        this.$message.error("请输入选项值!");
        return false;
      } else if (!this.addOption?.label) {
        this.$message.error("请输入选项名!");
        return false;
      }
      let data = {
        level: this.level,
        id: `${Date.parse(new Date())}_${Math.ceil(Math.random() * 99)}`,
        parentId: this.level != 0 ? this.selectData?.[this.level - 1].id : "",
        parent:
          this.level != 0 ? this.selectData?.[this.level - 1].value : "-1",
        parentLevel: this.level != 0 ? this.level - 1 : "-1",
        ...this.addOption,
        children: this.level < this.config.level - 1 ? [] : null,
      };
      (data.path =
        this.level == 0
          ? data.id
          : this.selectData?.[this.level - 1].path + "/" + data.id),
        // 向上传递新增的数据
        this.$emit("add", data, item);
      // 选中数据
      this.select(data, data.level);
      this.isAdd = false;
      this.addOption = {};
    },
    // 编辑数据
    editData(item) {
      // 判断是否已存在
      const list =
        this.level == 0
          ? this.data?.map((item) => item.label)
          : this.selectLists?.map((item) => item.label);
      if (list && list?.includes(this.addOption.label)) {
        // this.$message.error('选项名已存在，编辑失败!')
        // this.addOption = {}
        // this.isEdit = false
        // return false
      } else if (!this.addOption?.value) {
        this.$message.error("请输入选项值!");
        return false;
      } else if (!this.addOption?.label) {
        this.$message.error("请输入选项名!");
        return false;
      }
      // 向上传递新增的数据
      this.$emit("add", this.addOption, item);
      // 选中数据
      this.select(this.addOption, this.addOption?.level);
      this.isEdit = false;
      this.addOption = {};
    },
    // 选中数据项
    select(item, level) {
      this.$emit("change", { level: level, item: item });
    },
  },
};
</script>

<style lang="less" scoped>
.cascader-item {
  height: 100%;
  display: flex;
  //   width: 100%;
  .btlr {
    border-top-left-radius: 10px;
  }
  .btrr {
    border-top-right-radius: 10px;
  }
  .bl {
    border-left: 1px solid #d9d9d9;
    border-top-left-radius: 10px;
    border-bottom-left-radius: 10px;
  }
  .br {
    border-right: 1px solid #d9d9d9;
    border-top-right-radius: 10px;
    border-bottom-right-radius: 10px;
  }
  .add-option {
    padding: 5px 10px;
    .input {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 10px;
      .ant-input {
        margin-right: 10px;
        border-radius: 5px;
      }
      .tag {
        height: 32px;
        display: flex;
        justify-content: space-evenly;
        line-height: 32px;
        cursor: pointer;
      }
      &:last-child {
        margin-bottom: 0;
      }
    }
  }
  .left {
    height: 100%;
    border-top: 1px solid #d9d9d9;
    border-bottom: 1px solid #d9d9d9;
    .title {
      height: 40px;
      line-height: 40px;
      background: #f5f7fa;
      font-size: 16px;
      padding: 0 10px;
      border-bottom: 1px solid #d9d9d9;
    }
    .content {
      height: calc(100% - 70px);
      overflow-y: auto;
      .empty {
        height: 100%;
        align-items: center;
        display: flex;
        justify-content: center;
      }
      &::-webkit-scrollbar {
        /*滚动条整体样式*/
        width: 2px; /*高宽分别对应横竖滚动条的尺寸*/
        height: 1px;
      }
      &::-webkit-scrollbar-thumb {
        /*滚动条里面小方块*/
        border-radius: 2px;
        background: #e8e8e8;
      }
      &::-webkit-scrollbar-track {
        /*滚动条里面轨道*/
        border-radius: 2px;
        background: #ffffff;
      }
    }
    ul,
    li {
      margin: 0;
      padding: 0;
    }
    li {
      min-height: 30px;
      line-height: 30px;
      list-style: none;
      cursor: pointer;
    }
    .li-style {
      display: flex;
      justify-content: space-between;
      .btn {
        display: none;
      }
      &:hover {
        .btn {
          display: inline-flex;
        }
      }
    }
    .active {
      background: #eef4ff;
    }
    li,
    .add-plus {
      padding: 0 10px;
    }
    .add-plus {
      display: flex;
      justify-content: space-around;
      line-height: 30px;
      height: 30px;
      color: #409eff;
      text-align: center;
      cursor: pointer;
      background: #f5f7fa;
      border-top: 1px solid #d9d9d9;
    }
    .bbrr {
      border-bottom-right-radius: 10px;
    }
    .bblr {
      border-bottom-left-radius: 10px;
    }
  }
  .right {
    display: flex;
    .divider {
      height: 100%;
      margin: 0;
    }
  }
}
</style>
